package org.jeefb.modules.sys.service.impl;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import org.apache.log4j.Logger;
import org.jeefb.common.ServiceResult;
import org.jeefb.common.utils.ExceptionUtils;
import org.jeefb.core.redis.RedisKVManager;
import org.jeefb.modules.sys.contants.SystemCachedContants;
import org.jeefb.modules.sys.dao.SysDataRuleMapper;
import org.jeefb.modules.sys.dao.SysFunctionMapper;
import org.jeefb.modules.sys.dao.SysOperationMapper;
import org.jeefb.modules.sys.entity.SysFunction;
import org.jeefb.modules.sys.service.SystemService;
import org.jeefb.modules.sys.vo.DataRuleVO;
import org.jeefb.modules.sys.vo.MenuTreeVO;
import org.jeefb.modules.sys.vo.OperationVO;
import org.jeefb.modules.sys.vo.UserBaseVO;
import org.jeefb.modules.sys.vo.UserVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;

/**
 * 
 * @ClassName: SystemServiceImpl
 * @Description: 系统管理
 * @author genemax1107@aliyun.com
 * @date 2016年5月28日 上午10:06:25
 *
 */
@Service("systemService")
public class SystemServiceImpl implements SystemService {
	private static final Logger logger = Logger.getLogger(SystemServiceImpl.class);
	@Autowired
	private RedisKVManager redisKVManager;
	@Autowired
	private SysFunctionMapper sysFunctionMapper;
	@Autowired
	private SysOperationMapper sysOperationMapper;
	@Autowired
	private SysDataRuleMapper sysDataRuleMapper;

	/**
	 * 
	 * @Description: 查询用户权限信息
	 * @param userId
	 * @param sessionId
	 * @return
	 * @return ServiceResult<UserVO>
	 */
	public ServiceResult<UserVO> getUserVO(String userId, String sessionId) {
		ServiceResult<UserVO> result = new ServiceResult<UserVO>();
		try {
			UserVO userVO = new UserVO();
			String userJson = (String) redisKVManager.get(SystemCachedContants.ADMIN_USER_SESSION + sessionId);
			UserBaseVO userBaseVO = JSON.parseObject(userJson, UserBaseVO.class);
			userVO.setUserBaseVO(userBaseVO);
			// 用户菜单
			List<MenuTreeVO> functions = getUseFunction(userId, sessionId);
			userVO.setFunctions(functions);
			result.setResult(userVO);
		} catch (Exception e) {
			logger.error(ExceptionUtils.printExceptionInfo(e, userId));
			result.setSuccess(false);
		}
		return result;
	}

	/**
	 * 
	 * @Description: 获取菜单数据规则信息
	 * @param requestPath
	 * @return
	 * @return ServiceResult<List<DataRuleVO>>
	 */
	public ServiceResult<List<DataRuleVO>> getFunctionDataRules(String requestPath, String sessionId) {
		ServiceResult<List<DataRuleVO>> result = new ServiceResult<List<DataRuleVO>>();
		try {
			List<SysFunction> list = sysFunctionMapper.selectByFunctionUrl(requestPath);
			for (SysFunction sysFunction : list) {
				String dataRules = (String) redisKVManager
						.get(SystemCachedContants.ADMIN_DATA_RULE_SESSION + sessionId + ":" + sysFunction.getId());
				if (dataRules != null) {
					List<DataRuleVO> datas = JSON.parseArray(dataRules, DataRuleVO.class);
					result.setResult(datas);
				}
			}
		} catch (Exception e) {
			logger.error(ExceptionUtils.printExceptionInfo(e, requestPath));
			result.setSuccess(false);
		}
		return result;
	}

	/**
	 * 
	 * @Description: 查询路径是否在菜单功能中
	 * @param requestPath
	 * @return
	 * @return ServiceResult<Boolean>
	 */
	public ServiceResult<Boolean> getFunctionByUrl(String requestPath) {
		ServiceResult<Boolean> result = new ServiceResult<Boolean>();
		try {
			List<SysFunction> list = sysFunctionMapper.selectByFunctionUrl(requestPath);
			if (list != null && list.size() > 0) {
				result.setResult(true);
			} else {
			   result.setResult(false);
			}
			
		} catch (Exception e) {
			logger.error(ExceptionUtils.printExceptionInfo(e, requestPath));
			result.setSuccess(false);
		}
		return result;
	}

	/**
	 * 
	 * @Description: 获取用户功能
	 * @param userId
	 * @param sessionId
	 * @return
	 * @throws IllegalAccessException
	 * @throws InvocationTargetException
	 * @return List<FunctionVO>
	 */
	private List<MenuTreeVO> getUseFunction(String userId, String sessionId)
			throws IllegalAccessException, InvocationTargetException {
		List<MenuTreeVO> result = new ArrayList<MenuTreeVO>();
		// 机构功能
		List<SysFunction> orgFunctions = sysFunctionMapper.selectOrgFunctionByUserId(userId);
		// 角色功能
		List<SysFunction> roleFunctions = sysFunctionMapper.selectRoleFunctionByUserId(userId);
		// 合并去重
		roleFunctions.addAll(orgFunctions);
		Set<SysFunction> set = new HashSet<SysFunction>(roleFunctions);
		roleFunctions.clear();
		roleFunctions.addAll(set);
		List<String> functionIds = new ArrayList<String>();
		for (SysFunction sysFunction : roleFunctions) {
			functionIds.add(sysFunction.getId());
			result.add(chanageFunctionTOMenuVO(sysFunction));
		}
		// 菜单数据加载至缓存
		redisKVManager.set(SystemCachedContants.ADMIN_FUNCTION_SESSION + sessionId, JSON.toJSONString(result),
				SystemCachedContants.ADMIN_TIME_OUT, TimeUnit.MINUTES);
		result = sortMenuVO(result);
		if (functionIds.size() > 0) {
			// 将页面按钮，列表权限放置缓存
			List<OperationVO> operations = sysOperationMapper.selectByFunctionIds(functionIds);
			if (operations.size() > 0) {
				redisKVManager.set(SystemCachedContants.ADMIN_OPERATION_SESSION + sessionId,
						JSON.toJSONString(operations), SystemCachedContants.ADMIN_TIME_OUT, TimeUnit.MINUTES);
			}
			// 数据权限放置缓存
			List<DataRuleVO> dataRules = sysDataRuleMapper.selectByFunctionIds(functionIds);
			for (DataRuleVO dataRuleVO : dataRules) {
				redisKVManager.set(
						SystemCachedContants.ADMIN_DATA_RULE_SESSION + sessionId + ":" + dataRuleVO.getFunctionId(),
						JSON.toJSONString(operations), SystemCachedContants.ADMIN_TIME_OUT, TimeUnit.MINUTES);
			}
		}

		return result;
	}

	/**
	 * 
	 * @Description: 此数据必须按等级查询
	 * @param list
	 * @return
	 * @return List<MenuTreeVO>
	 */
	private List<MenuTreeVO> sortMenuVO(List<MenuTreeVO> list) {
		List<MenuTreeVO> rootTrees = new ArrayList<MenuTreeVO>();
		for (MenuTreeVO menuTreeVO : list) {
			if ("0".equals(menuTreeVO.getParentId())) {
				rootTrees.add(menuTreeVO);
			}
			for (MenuTreeVO childerens : list) {
				if (childerens.getParentId().equals(menuTreeVO.getId())) {
					if (menuTreeVO.getChildrens() == null) {
						List<MenuTreeVO> menuChildrens = new ArrayList<MenuTreeVO>();
						menuChildrens.add(childerens);
						menuTreeVO.setChildrens(menuChildrens);
					} else {
						menuTreeVO.getChildrens().add(childerens);
					}
				}
			}
		}
		return rootTrees;
	}

	/**
	 * 
	 * @Description: 值转换
	 * @param sysFunction
	 * @return
	 * @return MenuTreeVO
	 */
	private MenuTreeVO chanageFunctionTOMenuVO(SysFunction sysFunction) {
		MenuTreeVO menuTreeVO = new MenuTreeVO();
		menuTreeVO.setFunctionLevel(sysFunction.getFunctionLevel());
		menuTreeVO.setFunctionName(sysFunction.getFunctionName());
		menuTreeVO.setFunctionOrder(sysFunction.getFunctionOrder());
		menuTreeVO.setFunctionStyle(sysFunction.getFunctionStyle());
		menuTreeVO.setFunctionType(sysFunction.getFunctionType());
		menuTreeVO.setFunctionUrl(sysFunction.getFunctionUrl());
		menuTreeVO.setId(sysFunction.getId());
		menuTreeVO.setParentId(sysFunction.getParentId());
		return menuTreeVO;
	}

}
